package es

import (
	"context"
	"fmt"
	"gitee.com/manoshi/go-util/conf"
	"gitee.com/manoshi/go-util/log"
	"gitee.com/manoshi/go-util/util"
	"github.com/olivere/elastic/v7"
	"github.com/robfig/cron"
	_log "log"
	"os"
	"sync"
	"time"
)

func TestLog() {
	log.Info("Es 测试")
}

var client *elastic.Client
var esStatus int

var lockStatus sync.Mutex

func changeEsStatus(s int) {
	lockStatus.Lock()
	defer lockStatus.Unlock()
	esStatus = s
	if esStatus == 0 {
		checkInitEs()
	}
}

func GetEsStatus() int {
	return esStatus
}

func Init() {
	initEs()
}

var lock sync.Mutex

func initEs() {
	go connectEs()
}

func connectEs() {
	lock.Lock()
	defer lock.Unlock()
	if esStatus == 200 {
		return
	}
	host := fmt.Sprintf("http://%s:%d", conf.Es.ServerHost, conf.Es.ServerPort)
	var err error
	errorLog := _log.New(os.Stdout, "APP", _log.LstdFlags)
	client, err = elastic.NewClient(elastic.SetSniff(conf.Es.Sniff), elastic.SetErrorLog(errorLog), elastic.SetURL(host))
	ok := false
	if err != nil {
		log.Error(fmt.Sprintf("Elasticsearch connect error:%s", err.Error()))
	} else {
		info, code, err := client.Ping(host).Do(context.Background())
		log.Info(fmt.Sprintf("Elasticsearch connect %d", code))
		log.Info(fmt.Sprintf("Elasticsearch version %s", info.Version.Number))
		changeEsStatus(code)
		if err != nil {
			log.Error(fmt.Sprintf("Elasticsearch connect error:%s", err.Error()))
		} else {
			if code == 200 {
				go clearEsJob() //如果ES连接初始化成功，开启日期清理任务
				tickerStop()
				ok = true
			}
		}
	}
	if !ok {
		checkInitEs()
	}
}

var ticker *time.Ticker

func tickerStop() {
	if ticker != nil {
		ticker.Stop()
		ticker = nil
	}
}

var jobLock sync.Mutex

func checkInitEs() {
	go func() {
		jobLock.Lock()
		defer jobLock.Unlock()
		if esStatus == 200 {
			return
		}
		if ticker == nil {
			d := 30
			if conf.Es.CheckDuration != 0 {
				d = conf.Es.CheckDuration
			}
			ticker = time.NewTicker(time.Duration(d) * time.Second)
		}
		if ticker != nil {
			log.Info("等待ES恢复")
			select {
			case <-ticker.C:
				initEs()
			}
		}
	}()
}

func clearEsJob() {
	c := cron.New()
	var spec = util.If(conf.Es.ClearHisLogSpec == "", "0 0 6 * * *", conf.Es.ClearHisLogSpec)
	fmt.Println(spec)
	c.AddFunc(spec, func() {
		ClearESLog()
	})
	c.Start()
	log.Infof("开启ES日志清理任务 %d", conf.Es.StoreDays)
	select {}
}

func getRedisClient() *elastic.Client {
	return client
}

const (
	NewTermQuery               = "NewTermQuery"
	NewMatchPhraseQuery        = "NewMatchPhraseQuery"
	NewRegexpQuery             = "NewRegexpQuery"
	NewTermQueryNotMust        = "NewTermQueryNotMust"
	NewMatchPhraseQueryNotMust = "NewMatchPhraseQueryNotMust"
	NewRegexpQueryNotMust      = "NewRegexpQueryNotMust"
)
